package com.yonyou.pmclouds.task.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.billstatus.BillStatusConst;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.entity.MapList;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.SqlUtil;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemBillStatusConst;
import com.yonyou.pmclouds.inspectitem.entity.InspectItemVO;
import com.yonyou.pmclouds.inspectitem.rmiitf.InspectItemService;
import com.yonyou.pmclouds.picture.entity.PictureVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.plan.mapper.PlanWriteMapper;
import com.yonyou.pmclouds.project.entity.ProjectRefVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.stagecheck.entity.StageCheckVO;
import com.yonyou.pmclouds.stagecheck.rmitf.StageCheckQuery;
import com.yonyou.pmclouds.task.entity.TaskConst;
import com.yonyou.pmclouds.task.entity.TaskVO;
import com.yonyou.pmclouds.task.mapper.TaskMapper;
import com.yonyou.pmclouds.task.rmiitf.TaskQueryRemoteService;
import com.yonyou.pmclouds.workstartreport.entity.WorkStartCheckVO;
import com.yonyou.pmclouds.workstartreport.mapper.WorkStartCheckMapper;
import javafx.concurrent.Task;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
@Slf4j
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = TaskQueryRemoteService.class)
public class TaskQueryRemoteServiceImpl implements TaskQueryRemoteService {

    @Autowired
    private TaskMapper taskMapper;
    @Autowired
    private ProjectSimpleQuery projectService;
    @Autowired
    private PictureRemoteService picService;
    @Autowired
    private WorkStartCheckMapper checkMapper;
    @Autowired
    private PlanWriteMapper planWriteMapper;
    @Autowired
    private InspectItemService itemService;
    @Autowired
    private StageCheckQuery stageCheckQuery;

    @Override
    public List<TaskVO> queryTodoTaskList(String pk_receiver) throws BusinessException {

        List<TaskVO> taskList = taskMapper.queryTodoTaskList(pk_receiver);

        fillBusiInfo(taskList);

        fillPicInfo(taskList);

        return taskList;
    }

    @Override
    public List<TaskVO> queryDoneTaskList(String pkReceiver, int start, int size) throws BusinessException {
        List<TaskVO> doneTaskList = taskMapper.getDoneTaskList(pkReceiver, start, size);
        return fillBusiInfo(doneTaskList);
    }

    @Override
    public List<TaskVO> queryDoneTaskListExceptReject(String pkReceiver, int start, int size) throws BusinessException {
        List<TaskVO> doneTaskList = taskMapper.getDoneTaskListExceptBIllStatus(pkReceiver, new byte[]{BillStatusConst.COMMON_COMMIT_STATUS}, start, size);
        return fillBusiInfo(doneTaskList);
    }

    @Override
    public List<TaskVO> queryOwnLaunchBills(String taskcreator, int start, int size) throws BusinessException {

        String[] excludeTypes = new String[]{BillTypeConst.PROCESS_PLAN_BILLTYPE};

        long startTime = System.currentTimeMillis();
        List<TaskVO> queryList = taskMapper.queryOwnLaunchBills(taskcreator, excludeTypes, start, size);

        log.info("查询已发起的耗时：" + (System.currentTimeMillis() - startTime));

        fillBusiInfo(queryList);

        return queryList;
    }

    @Override
    public Map<String, List<TaskVO>> queryRelateMeBill(String pk_user) throws BusinessException {
        List<TaskVO> todoTaskList = queryTodoTaskList(pk_user);
        List<TaskVO> ownLanuchList = queryOwnLaunchBills(pk_user, 0, 20);

        Map<String, List<TaskVO>> relateMeTaskMap = new HashMap<String, List<TaskVO>>();
        relateMeTaskMap.put("todoList", todoTaskList);
        relateMeTaskMap.put("ownLanuchList", ownLanuchList);

        return relateMeTaskMap;
    }

    @Override
    public TaskVO[] queryTaskByBillAndReceiver(String[] pk_bills, String pk_receiver) throws BusinessException {

        TaskVO[] preTaskVOs = taskMapper.queryTaskByBillAndReceiver(pk_bills, pk_receiver, TaskConst.TASK_TODO);

        return preTaskVOs;
    }

    @Override
    public TaskVO[] queryByPretask(String[] pkPretasks) throws BusinessException {
        if (ArrayUtils.isEmpty(pkPretasks)) return new TaskVO[0];
        return taskMapper.queryByPreTask(SqlUtil.getSqlIn(pkPretasks));
    }


    /**
     * 待办消息增加图片信息
     *
     * @param queryList
     * @return
     * @throws BusinessException
     */
    private List<TaskVO> fillPicInfo(List<TaskVO> queryList) throws BusinessException {
        // 1.根据类型对单据分组。分为表头、施工记录、开工报告，以后如果再有特殊的表体关联图片单据，这里需要增加分组，以便后面查询
        Map<String, List<String>> typeBillMap = grpPkBillByType(queryList);

        // 2.获得所有关联照片的实体ID
        List<String> pkEntityList = getPkEntitysList(typeBillMap);

        // 3.查询待办对应单据实体所关联的所有照片
        Map<String, List<PictureVO>> picMap = picService.queryByLargePkEntities(pkEntityList.toArray(new String[0]));
        if (picMap == null || picMap.size() <= 0)
            return queryList;
        // 4.根据单据id（表头id）对查出来的图片进行再分组
        MapList<String,String> billPicMap = grpPicsByPkBill(picMap);
        // 5.给待办任务对应的图片
        for (TaskVO taskVO : queryList) {
            if (taskVO == null)
                continue;
            if (billPicMap.get(taskVO.getPk_bill()) != null && billPicMap.get(taskVO.getPk_bill()) .size()>0)
                taskVO.setPictures(billPicMap.get(taskVO.getPk_bill()));
        }

        return queryList;
    }

    /**
     * 依据单据表头id，对图片进行重新分组
     *
     * @param picMap
     * @return
     */
    private MapList<String,String> grpPicsByPkBill(Map<String, List<PictureVO>> picMap) {
        MapList<String,String> billPicMap = new MapList<>();
        for (List<PictureVO> picList : picMap.values()){
            if (picList !=null && picList.size()>0){
                for (PictureVO picVO : picList){
                    if(billPicMap.get(picVO.getPk_bill())!= null && billPicMap.get(picVO.getPk_bill()).size() >= 9)
                        break;
                    billPicMap.put(picVO.getPk_bill(),picVO.getPicture_name());
                }
            }
        }
        return billPicMap;
    }

    /**
     * 根据单据类型和表头id获取真正关联图片的实体id
     *
     * @param typeBillMap
     * @return
     */
    private List<String> getPkEntitysList(Map<String, List<String>> typeBillMap) throws BusinessException{
        // 对于表体关联图片的实体，分类获取符合条件的表体id
        List<String> pkEntityList = getEntityIDs(typeBillMap);
        // 获得表头id
        if(typeBillMap.get("HEAD_TYPE") != null){
            pkEntityList.addAll(typeBillMap.get("HEAD_TYPE"));
        }
        return pkEntityList;
    }

    /**
     * 对于表体有照片的单据，分类获取符合条件的表体id
     * TODO 可能以后需要增加直接查询不合格表体的接口，避免直接持有mapper，还是应该面向接口
     *
     * @param typeBillMap
     * @return
     */
    private List<String> getEntityIDs(Map<String, List<String>> typeBillMap) throws BusinessException{
        List<String> pkEntityList = new ArrayList<>();
        Date before = new Date();
        if(typeBillMap.get(BillTypeConst.WORKSTART_BILLTYPE) != null){
            WorkStartCheckVO[] workStartCheckVOS = checkMapper.selectByBills(SqlUtil.getSqlIn(typeBillMap.get(BillTypeConst.WORKSTART_BILLTYPE).toArray(new String[0])));
            if (ArrayUtils.isNotEmpty(workStartCheckVOS)) {
                for (WorkStartCheckVO vo : workStartCheckVOS) {  //取不合格的检查项
                    if (vo != null && vo.getPkCheck() != null&&vo.getQualification()!=null&&vo.getQualification()==2) {
                        pkEntityList.add(vo.getPkCheck());
                    }
                }
            }
        }

        String[] pkCheckBills = new String[]{};
        if(typeBillMap.get(BillTypeConst.CONSTRUCTIONLOG_BILLTYPE)!=null){
            pkCheckBills = ArrayUtils.addAll(pkCheckBills,typeBillMap.get(BillTypeConst.CONSTRUCTIONLOG_BILLTYPE).toArray(new String[0]));
        }
        if(typeBillMap.get(BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE)!=null){
            pkCheckBills = ArrayUtils.addAll(pkCheckBills,typeBillMap.get(BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE).toArray(new String[0]));
        }
        if(typeBillMap.get(BillTypeConst.STAGECHECK_BILLTYPE)!=null){
            pkCheckBills = ArrayUtils.addAll(pkCheckBills,typeBillMap.get(BillTypeConst.STAGECHECK_BILLTYPE).toArray(new String[0]));
        }

        if (ArrayUtils.isNotEmpty(pkCheckBills)){
            InspectItemVO[] inspectItemVOs = itemService.queryByPkBillsAndStatus(pkCheckBills, (int) InspectItemBillStatusConst.BILLSTATUS_NO_PASS);
//            InspectItemVO[] inspectItemVOs = inspectItemMapper.queryByPkBillsAndStatus(pkCheckBills,(int) InspectItemBillStatusConst.BILLSTATUS_NO_PASS);
            if (ArrayUtils.isNotEmpty(inspectItemVOs)) {
                for (InspectItemVO vo : inspectItemVOs) {
                    pkEntityList.add(vo.getPk_inspectitem());

                }
            }
        }

        return pkEntityList;
    }

    /**
     * 根据单据类型对代办中涉及到的单据进行分类
     *
     * @param queryList
     * @return
     */
    private Map<String, List<String>> grpPkBillByType(List<TaskVO> queryList) {
        Map<String,List<String>> typeBillMap = new HashMap<>();
        for (TaskVO taskVO : queryList){
            if (taskVO != null) {
                if (BillTypeConst.CONSTRUCTIONLOG_BILLTYPE.equals(taskVO.getSrc_bill_type()) ||
                        BillTypeConst.COMPREHENSIVE_ACCEPTANCE_BILLTYPE.equals(taskVO.getSrc_bill_type()) ||
                        BillTypeConst.WORKSTART_BILLTYPE.equals(taskVO.getSrc_bill_type()) ||
                        BillTypeConst.STAGECHECK_BILLTYPE.equals(taskVO.getSrc_bill_type())) {
                    if(typeBillMap.get(taskVO.getSrc_bill_type()) == null)
                        typeBillMap.put(taskVO.getSrc_bill_type(),new ArrayList<String>());
                    typeBillMap.get(taskVO.getSrc_bill_type()).add(taskVO.getPk_bill());
                } else {
                    if(typeBillMap.get("HEAD_TYPE") == null)
                        typeBillMap.put("HEAD_TYPE",new ArrayList<String>());
                    typeBillMap.get("HEAD_TYPE").add(taskVO.getPk_bill());
                }
            }
        }
        return typeBillMap;
    }

    /**
     * 为taskVO添加必要的业务信息
     */
    private List<TaskVO> fillBusiInfo(List<TaskVO> queryList) throws BusinessException {
        // 这里需要设置查询单据类型名称 项目名称
        Map<String, List<TaskVO>> prjTaskMap = new HashMap<String, List<TaskVO>>();

        for (TaskVO taskVO : queryList) {
            if (prjTaskMap.get(taskVO.getPk_project()) == null) {
                prjTaskMap.put(taskVO.getPk_project(), new ArrayList<TaskVO>());
            }

            prjTaskMap.get(taskVO.getPk_project()).add(taskVO);

        }
        Map<String, ProjectRefVO> prjRefMap = projectService.queryRefs(prjTaskMap.keySet().toArray(new String[0]));

        String tempProject = null;
        for (TaskVO taskVO : queryList) {
            tempProject = taskVO.getPk_project();
            taskVO.setProject_name(prjRefMap.get(tempProject) == null ? "" : prjRefMap.get(tempProject).getSname());
        }
        //对于 阶段验收添加对应的检查标准 检查任务名称 这里可以考虑定义 待办消息模板
        HashMap<String, TaskVO> pk2Task = new HashMap<>();
        for (TaskVO taskVO : queryList) {
            if (BillTypeConst.STAGECHECK_BILLTYPE.equals(taskVO.getSrc_bill_type())) {
               pk2Task.put(taskVO.getPk_bill(),taskVO);
            }
        }
        if (!pk2Task.isEmpty()) {
            StageCheckVO[] stageCheckVOS = stageCheckQuery.queryByPks(pk2Task.keySet());
            if (ArrayUtils.isNotEmpty(stageCheckVOS)) {
                for (StageCheckVO stageCheckVO : stageCheckVOS) {
                    TaskVO taskVO = pk2Task.get(stageCheckVO.getPkStageCheck());
                    taskVO.addProp("planName",stageCheckVO.getScheduleItemVO() == null ? "" : stageCheckVO.getScheduleItemVO().getName());
                    taskVO.addProp("checkName",stageCheckVO.getInspectstandardName());
                    taskVO.addProp("rate",stageCheckVO.getRate());
                }
            }
        }
        return queryList;
    }

}
